package com.warm.pump.module.skd.service.impl;

import com.warm.pump.executor.InstanceService;
import com.warm.pump.executor.TaskQuartzUtils;
import com.warm.pump.frame.gen.bean.PageBean;
import com.warm.pump.frame.util.ScheduleStatus;
import com.warm.pump.module.skd.bean.po.gen.ScheduleJob;
import com.warm.pump.module.skd.bean.po.gen.ScheduleJobDtl;
import com.warm.pump.module.skd.dao.gen.ScheduleJobDao;
import com.warm.pump.module.skd.dao.gen.ScheduleJobDtlDao;
import com.warm.pump.module.skd.service.IScheduleJobService;
import com.warm.pump.module.work.bean.po.gen.Work;
import com.warm.pump.module.work.dao.gen.WorkDao;
import org.quartz.CronTrigger;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.*;


@Service("ScheduleJobService")
public class ScheduleJobServiceImpl implements IScheduleJobService {
	@Autowired
	private ScheduleJobDao scheduleJobDao;
	@Autowired
	private ScheduleJobDtlDao scheduleJobDtlDao;
	@Autowired
	private InstanceService instanceService;
	@Autowired
	private Scheduler scheduler;
	@Autowired
	private WorkDao workDao;



	/**
	 * 项目启动时，初始化定时器
	 */
	@PostConstruct
	public void init() {
		List<ScheduleJob> jobList = scheduleJobDao.getListByMap(new HashMap<String, Object>());
		// 任务开始时间
		long startTime = System.currentTimeMillis();
		for (ScheduleJob job : jobList) {
			CronTrigger cronTrigger = TaskQuartzUtils.getCronTrigger(scheduler, job.getId());
			// 如果不存在，则创建
			if (cronTrigger == null) {
				TaskQuartzUtils.createScheduleJob(scheduler, job);
			} else {
				TaskQuartzUtils.updateScheduleJob(scheduler, job);
			}
		}
		// 任务执行总时长
		long times = System.currentTimeMillis() - startTime;
	}

	@Override
	public ScheduleJob queryObject(Long  id){
		return scheduleJobDao.selectByPrimaryKey( id);
	}

	public ScheduleJob queryObject(Map<String, Object> map){
		return scheduleJobDao.selectByMap( map);
	}
	
	@Override
	public List<ScheduleJob> queryList(Map<String, Object> map){
		return scheduleJobDao.getListByMap(map);
	}

    @Override
    public PageBean getPageBeanByMap(Map map,int pageNo,int pageSize) {
		return scheduleJobDao.getPageBeanByMap(map, pageNo, pageSize);
    }


	@Override
	public int queryTotal(Map<String, Object> map){
		return scheduleJobDao.countTotalByMap(map);
	}
	
	@Override
	@Transactional
	public void save(ScheduleJob scheduleJob){
		scheduleJobDao.insertSelective(scheduleJob);
		TaskQuartzUtils.createScheduleJob(scheduler,scheduleJob);
	}
	
	@Override
	@Transactional
	public void update(ScheduleJob scheduleJob){
		scheduleJobDao.updateByPrimaryKeySelective(scheduleJob);
		ScheduleJob updateJob = scheduleJobDao.selectByPrimaryKey(scheduleJob.getId());
		TaskQuartzUtils.updateScheduleJob(scheduler,updateJob);
	}
	
	@Override
	public void delete(Long  id){
		scheduleJobDao.deleteByPrimaryKey(id);
	}

	@Override
	public void delete(Map<String, Object>  map){
	scheduleJobDao.deleteByMap(map);
	}
	
	@Override
	public void deleteBatch(Long[]  ids){
		for (Long id : ids) {
			TaskQuartzUtils.deleteScheduleJob(scheduler, id);
		}

		Map<String, Object> map = new HashMap<>();
		map.put("id_in",ids);
		scheduleJobDao.deleteByMap(map);
	}

	/**
	 * 立即执行
	 */
	@Transactional
	public void run(Long[] ids) {
		for (Long id : ids) {
			this.createInstBySdkJob(id);
		}
	}

	/**
	 * 立即执this行
	 */
	public void  run (Long id ,String params){
		this.createInstBySdkJob(id,params);
	}


	/**
	 * 通过调度任务创建实例
	 *
	 * @param skdJobId
	 */
	@Transactional
	public void createInstBySdkJob(Long skdJobId){
		createInstBySdkJob(skdJobId,null);
	}


	/**
	 * 通过调度任务创建实例
	 * @param skdJobId
	 * @param params
	 */
	@Transactional
	public void createInstBySdkJob(Long skdJobId,String params) {
		ScheduleJob scheduleJob = scheduleJobDao.selectByPrimaryKey(skdJobId);

		//查询归属该任务的 专题列表
		Map<String, Object> dtlMap = new HashMap<>();
		dtlMap.put("jobId", scheduleJob.getId());
		dtlMap.put("type", "workSubject");
		dtlMap.put("orderBy", "exec_num");
		List<ScheduleJobDtl> jobDtlSubjectList = scheduleJobDtlDao.getListByMap(dtlMap);

		List<ScheduleJobDtl> itemJobDtlList = new ArrayList<>();
		if (null != jobDtlSubjectList && jobDtlSubjectList.size() > 0) {
			//迭代专题列表 获取该任务专题下作业集
			for (ScheduleJobDtl jobDtl : jobDtlSubjectList) {
				Map<String, Object> itemMap = new HashMap<>();
				itemMap.put("type", "workItem");
				itemMap.put("pid", jobDtl.getId());
				itemMap.put("orderBy", "exec_num");
				List<ScheduleJobDtl> subDtlList = scheduleJobDtlDao.getListByMap(itemMap);
				if (null != subDtlList && subDtlList.size() > 0) {
					itemJobDtlList.addAll(subDtlList);
				}
			}
		}
		//创建任务实例
		if (itemJobDtlList.size() > 0) {
			String instId = instanceService.createInst("scheduleJob", scheduleJob.getId(), scheduleJob.getJobName(), itemJobDtlList.size(), "通过任务产生实例",scheduleJob.getMisfireInformIds());
			for (ScheduleJobDtl itemJobDtl : itemJobDtlList) {
				Work work = workDao.selectByPrimaryKey(itemJobDtl.getWorkId());
				if (null != work && null != work.getId()) {
					instanceService.createInstDtl(instId, work.getId(), work.getWorkName(), null, null, params);
				}
			}
		}
	}
	/**
	 * 暂停运行
	 */
	@Transactional
	@Override
	public void pause(Long[] ids) {
		for (Long id : ids) {
			TaskQuartzUtils.pauseJob(scheduler, id);
		}


		updateBatch(ids, ScheduleStatus.PAUSE.getValue());
	}

	/**
	 * 恢复运行
	 */

	@Transactional
	@Override
	public void resume(Long[] ids) {
		for (Long id : ids) {
			TaskQuartzUtils.resumeJob(scheduler, id);
		}

		updateBatch(ids, ScheduleStatus.NORMAL.getValue());
	}

	/**
	 * 批量更新定时任务状态
	 */
	@Override
	public boolean updateBatch(Long[] ids, int status) {
		Map<String, Object> map = new HashMap<>();
		map.put("id_in", ids);
		ScheduleJob job = new ScheduleJob();
		job.setStatus(status);
		job.setUpdateTime(new Date());
		return scheduleJobDao.updateByMapSelective(job, map);
	}
	
}
